package cn.edu.mju.auth.handler;

import cn.edu.mju.auth.mapper.IAuthUserInfoMapper;
import cn.edu.mju.auth.secu.LoginUser;
import cn.edu.mju.common.entity.pojo.UserInfo;
import cn.edu.mju.common.entity.result.ResponseResult;
import cn.edu.mju.common.entity.vo.user.UserInfoVO;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.Setter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author 16423
 */

@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {


    @Setter(onMethod_ = @Autowired)
    private IAuthUserInfoMapper iAuthUserInfoMapper;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    private final RestTemplate restTemplate;

    //jwt请求路径
    private final String tokenEndpoint = "http://localhost:8889/sso/oauth/token"; // OAuth2 Token Endpoint
    private final String clientId = "client"; // OAuth2 Client id
    private final String clientSecret = "secret"; // OAuth2 Client Secret

    public LoginSuccessHandler() {
        this.restTemplate = new RestTemplate();
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        //获取认证用户信息
        LoginUser user = (LoginUser) authentication.getPrincipal();
        //获取用户明文密码
        String pwd = response.getHeader("pwd");


        // 构建请求体参数
        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("grant_type", "password");
        requestBody.add("username", user.getUsername());
        requestBody.add("password", pwd);

        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setBasicAuth(clientId, clientSecret);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // 发送 POST 请求获取 Token
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);
        ResponseEntity<OAuth2AccessToken> responseEntity = restTemplate.exchange(tokenEndpoint, HttpMethod.POST, requestEntity, OAuth2AccessToken.class);
        OAuth2AccessToken token = responseEntity.getBody();

        //获取用户基本信息
        LambdaQueryWrapper<UserInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UserInfo::getUserId,user.getUser().getUserId());
        UserInfo userInfo = iAuthUserInfoMapper.selectOne(lqw);

        UserInfoVO vo = new UserInfoVO();
        //封装用户信息
        BeanUtils.copyProperties(userInfo,vo);

        //更新最后登录时间
        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime startDateTime = LocalDateTime.parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LambdaUpdateWrapper<UserInfo> luw = new LambdaUpdateWrapper<>();
        luw.set(UserInfo::getLastLoginTime,startDateTime);
        luw.eq(UserInfo::getUserId,vo.getUserId());
        int count = iAuthUserInfoMapper.update(null, luw);


        //设置返回信息
        HashMap<String,Object> r = new HashMap<>();
        r.put("token",token.getValue());
        r.put("userInfo",vo);



        //登录成功后，将token存入统一redis中
        System.out.println(token.getValue());
        redisTemplate.opsForValue().set(token.getValue(),"true",1, TimeUnit.DAYS);

        //测试
        String i = token.getValue();
        System.out.println("-----"+redisTemplate.opsForValue().get(i));


        //返回相应数据
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        response.getWriter().println(JSONObject.toJSONString(ResponseResult.okResult(r)));
    }
}
